unit Piece;

{$mode objfpc}{$H+}

//棋子 Chess Piece
//中文表示，
//在字符集GBK下，原则上红方以简体字表示，黑方以繁体字表示
//GBK红方：车马相仕帥炮兵
//GBK黑方：車馬象士將砲卒
//在GB2312一级汉字库中，繁体字(帥,將)不能显示时，棋子表示为：
//GB 红方：车马相仕帅炮兵
//GB 黑方：車馬象士将砲卒
//或：伡=車,犸=馬
//以上表示法主要考虑在没有颜色区分下，仍能分别表示红黑方棋子。
//程序符号，
//Char红方：A=车,B=马,C=相,D=仕,E=帅,F=炮,G=兵
//Char黑方：H=車,I=馬,J=象,K=士,L=将,M=砲,N=卒
//数字表示: A=1 ,B=2 ,C=3 ,D=4 ,E=5 ,F=6 ,G=7
//          H=8 ,I=9 ,J=10,K=11,L=12,M=13,N=14

//棋子价值(Cost)
//车(A)/車(H) = 9
//马(B)/馬(I) = 4
//相(C)/象(J) = 2
//仕(D)/士(L) = 2
//帅(E)/将(K) = 0
//炮(F)/砲(M) = 4.5
//兵(G)/卒(N),未过河= 1，已过河=2，到底线的兵（由于只能左右移动）——1分

//走子规则不在本类中体现，而在规则Ruler类中表示。
//局中的棋子价值增减由局面计算，如马被拌脚1只减0.5分。或者将胜加1000分，将败减1000分。

interface

uses
  Classes, SysUtils;

  const
    cSideBlk :AnsiChar = 'B';
    cSideRed :AnsiChar = 'R';
  //避免代码更改替换时意外错乱，以常量标识棋子代码
    cRA_Ju :AnsiChar = 'A'; //车(A)/車(H)
    cRB_Ma :AnsiChar = 'B'; //马(B)/馬(I)
    cRC_Xng :AnsiChar = 'C'; //相(C)/象(J)
    cRD_Shi :AnsiChar = 'D'; //仕(D)/士(L)
    cRE_Jng :AnsiChar = 'E'; //帅(E)/将(K)
    cRF_Pao :AnsiChar = 'F'; //炮(F)/砲(M)
    cRG_Zu :AnsiChar = 'G'; //兵(G)/卒(N)

    cBH_Ju :AnsiChar = 'H'; //车(A)/車(H)
    cBI_Ma :AnsiChar = 'I'; //马(B)/馬(I)
    cBJ_Xng :AnsiChar = 'J'; //相(C)/象(J)
    cBK_Shi :AnsiChar = 'K'; //仕(D)/士(L)
    cBL_Jng :AnsiChar = 'L'; //帅(E)/将(K)
    cBM_Pao :AnsiChar = 'M'; //炮(F)/砲(M)
    cBN_Zu :AnsiChar = 'N'; //兵(G)/卒(N)

type

  { TPiece }

  TPiece = class(TObject)
  private

  protected
  public
    bID:Byte; //1~14 //A~N
    cCode:AnsiChar;//A~N
    cSide:AnsiChar;//cSideRed=Red /cSideBlk=Black
    sName:string; //中文名称
    iCost:real; //初始值
    constructor Create;
    destructor Destroy; override;
    procedure setCode(const code:AnsiChar);
    procedure setID(const nID:Byte);
    property Code :AnsiChar read cCode Write setCode;
    property ID :Byte read bID Write setID;

  end;

var
  //public float xCost=0.0f; //兵卒过河后附加值=1.0
  namesJFT:array[0..14] of string = (' ','车','马','相','仕','帥','炮','兵','車','馬','象','士','將','砲','卒');
  names_JT:array[0..14] of string = (' ','车','马','相','仕','帅','炮','兵','車','馬','象','士','将','砲','卒');
  useCharset:string = 'JT';

  char2ID:array[0..255] of Byte;
  isInit_char2ID : boolean =false;
  //bID2Char:array[0..14] of AnsiChar = (' ','A','B','C','D','E','F','G','H','I','J','K','L','M','N');
  bID2Char:array[0..14] of AnsiChar = (' ',cRA_Ju,cRB_Ma,cRC_Xng,cRD_Shi,cRE_Jng,cRF_Pao,cRG_Zu
                                          ,cBH_Ju,cBI_Ma,cBJ_Xng,cBK_Shi,cBL_Jng,cBM_Pao,cBN_Zu);
  bID2iCost:array[0..14] of real = (0, 9 ,4 ,2 ,2  ,0,4.5,1 ,9 ,2 ,2 ,4 ,0,4.5,1); //静态价值,帅/将不计价

  procedure init_char2ID();
  //求棋子属于哪一方
  function getName(const code:AnsiChar):String ;
  function getSide(const code:AnsiChar):AnsiChar ;

implementation

procedure init_char2ID();
var c:Byte;
begin
  for c:=0 to 255 do
  begin
  	char2ID[c]:=0;
  end;
  //A~N:1~14
  for c:=65 to 78 do
  begin
  	char2ID[c]:= c-64;  //A=65:1, 66:2,
  end;
  //a~g:2,4,6,8,10,12,14
  isInit_char2ID:=true;
end;

function getName(const code:AnsiChar):String ;
var aID:Byte;
begin
  aID:=char2ID[Ord(code)];
  if (useCharset='JT') then begin
    	//Result := names_JT[char2ID[Ord(code)]];
  	Result := names_JT[aID];
  end else begin
  	//Result := namesJFT[char2ID[Ord(code)]];
  	Result := namesJFT[aID];
  end;
end;

function getSide(const code:AnsiChar):AnsiChar ;
begin
  if ((code>='A')and(code<='G')) then begin
  	Result:= cSideRed;
  end else if ((code>='H')and(code<='N')) then begin
  	Result:= cSideBlk;
  end else begin
  	Result:= ' ';
  end;
end;

{ TPiece }

constructor TPiece.Create;
begin
  inherited Create();
end;

destructor TPiece.Destroy;
begin
  inherited Destroy;
end;

procedure TPiece.setCode(const code: AnsiChar);
begin
  cCode := code;
  cSide := getSide(code);
  bID := char2ID[Ord(code)];
  if (useCharset='JT') then begin
  	sName := names_JT[bID];
  end else begin
  	sName := namesJFT[bID];
  end;
  iCost := bID2iCost[bID];

end;

procedure TPiece.setID(const nID: Byte);
begin
  		bID := nID;
		cCode := bID2Char[nID];
                cSide := getSide(code);
		if (useCharset='JT') then begin
			sName := names_JT[bID];
		end else begin
			sName := namesJFT[bID];
		end;
		iCost := bID2iCost[bID];

end;

initialization
   init_char2ID();
finalization

end.

